/*
 * video-text.c
 *
 *  Created on: 28/Fev/2010
 *      Author: �ngela Igreja
 */

#include "video-text.h"

/** Calculate memory offset for writing at position x, y
 * return unsigned long - Posi��o de Mem�ria
 */
ulong calcMemPosition(int x, int y)
{
	return VIDEO_TEXT + (y * (WIDTH * 2) + x * 2); // y-linha(i); x-coluna(j)
}


/** Get character at position x, y
 * return int
 */
int getCharAt(int x, int y)
{
	if (x < 0 || x >= WIDTH || y < 0 || y >= HEIGHT)
		return -1;

	_farsetsel(_dos_ds); /* always use _dos_ds in this function */
	return _farnspeekb(calcMemPosition(x, y));
}


/** Get attributes at position x, y
 * return int
 */
int getAttributesAt(int x, int y)
{
	if(x < 0 || x >= WIDTH || y < 0 || y >= HEIGHT)
		return -1;

	_farsetsel(_dos_ds); /* always use _dos_ds in this function */
	return _farnspeekb(calcMemPosition(x, y) + 1); // 2�Byte - Attributes
}


/** Print character ch at position x,y with attributes
* return true if sucessfull
*/
Bool printCharAt(char ch, int x, int y, char attributes)
{
	if(x < 0 || x >= WIDTH || y < 0 || y >= HEIGHT)
		return false;

	_farsetsel(_dos_ds); /* always use _dos_ds in this function */
	_farnspokeb(calcMemPosition(x, y), ch);
	_farnspokeb(calcMemPosition(x, y) + 1, attributes);
	return true;
}


void clear( char attributes )
{
	int x = 0;
	int y = 0;
	for ( x = 0 ; x < WIDTH ; ++x )
		for ( y = 0; y < HEIGHT ; ++y )
			printCharAt(' ' , x , y, attributes);
}

/** Print character array str at position x,y with attributes
* return true if sucessfull
*/
Bool printStringAt(char *str, int x, int y, char attributes)
{
	int i = 0;

	while(str[i] != 0)
	{
		if(!printCharAt(str[i], x + i, y, attributes)) return false;
		i++;
	}

	return true;
}


/** Print integer num at position x,y with attributes.
* No C library function is used.
* return true if sucessfull
*/
Bool printIntAt(int num, int x, int y, char attributes)
{
	int i = 0;

	//Se o n�mero for negativo, imprimir '-'

	if(num < 0)
	{
		if(!printCharAt('-', x, y, attributes))
			return false;
		i++;
		num = - num; // Colocar o n�mero positivo
	}

	// Descobrir a ordem de grandeza do numero
	int ordem = 1;

	while(num / ordem >= 10)
		ordem *= 10;

	// Imprimir os algarismos, da esquerda para a direita,
	while(true)
	{
		int digito = num / ordem;

		if(!printCharAt(digito + 0x30, x + i, y, attributes))
			return false;
		num -= digito * ordem;

		if(ordem == 1)
			break;
		ordem /= 10;
		i++;
	}
	return true;
}


/** Draw rectangular frame with left upper corner at position x,y
* with width and height dimensions, decorated with title attributes.
* return true if sucessfull
*/
Bool drawFrame(char * title, char attributes, int x, int y, int width, int height)
{
	int x_final = x + width - 1;
	int y_final = y + height - 1;

	if(!printCharAt(0xC9, x, y, attributes))		//canto superior esquerdo
		return false;			
	if(!printCharAt(0xBB, x_final, y, attributes))		//canto superior direito
		return false;		
	if(!printCharAt(0xC8, x, y_final, attributes))		//canto inferior esquerdo
		return false;		
	if(!printCharAt(0xBC, x_final, y_final, attributes))	//canto inferior direito
		return false;	
	int i = x + 1;

	for( ; i < x_final; i++)
	{
		printCharAt(0xCD, i, y, attributes);						//margem superior
		printCharAt(0xCD, i, y_final, attributes);					//margem inferior
	}

	int j = y + 1;
	for( ; j < y_final; j++)
	{
		printCharAt(0xBA, x, j, attributes);						//margem esquerda
		printCharAt(0xBA, x_final, j, attributes);					//margem direita
	}

	// Verificar se o t�tulo cabe na moldura

	int title_size = 0;

	while(title[title_size] != '\0')
		title_size++;

	if(title_size > width - 2)
		return false;
	printStringAt(title, (x_final - x) / 2, y + 1, attributes);					//t�tulo
	return true;
}
